package com.yuntsg.ruiijn.controller.system;


import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.junrar.Archive;
import com.github.junrar.rarfile.FileHeader;
import com.yuntsg.ruiijn.database.entity.TextSelfMd5;
import com.yuntsg.ruiijn.database.mapper.TextSelfDbMapper;
import com.yuntsg.ruiijn.database.mapper.TextSelfMd5Mapper;
import com.yuntsg.ruiijn.paperana.test.PDFTextStripper2;
import com.yuntsg.ruiijn.paperana.utils.StrUtils;
import com.yuntsg.nnsfcp.common.beans.ResultBean;
import common.util.CheckUtil;
import common.util.FileUtils;
import com.yuntsg.nnsfcp.common.utils.UserUtil;
//import io.swagger.annotations.Api;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.yuntsg.ruiijn.paperana.utils.StrUtils.existZH;
import static com.yuntsg.ruiijn.service.AsyncService.localDateFilePath;
import static common.util.EncryptionUtil.decryptWithAES;

@RestController
@RequestMapping("upload")
@Slf4j
@SuppressWarnings("ALL")
//@Api(tags = "文件上传")
public class UploadController {
    @Value("${upload.path}")
    public String uploadPath;

    @Value("${upload.temprarPath}")
    public String temprarPath;

    @Value("${upload.key}")
    public String mdkey;

    @Resource
    UserUtil userUtil;

    @Resource
    TextSelfDbMapper textSelfDbMapper;

    @Resource
    TextSelfMd5Mapper textSelfMd5Mapper;

    public synchronized static void convertTiffToJpg(String tiffFilePath, String jpgFilePath) throws IOException {

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 读取 TIF 图片
        System.out.println("输入文件_" + tiffFilePath);
        System.out.println("输出文件_" + jpgFilePath);

        BufferedImage tiffImage = ImageIO.read(new File(tiffFilePath));

        // 创建 JPG 图片文件
        File jpgFile = new File(jpgFilePath);

        // 将 TIF 图片写入 JPG 文件
        ImageIO.write(tiffImage, "PNG", jpgFile);
    }

    static BufferedImage ensureOpaque(BufferedImage bi) {
        if (bi.getTransparency() == BufferedImage.OPAQUE) {
            return bi;
        }
        int w = bi.getWidth();
        int h = bi.getHeight();
        int[] pixels = new int[w * h];
        bi.getRGB(0, 0, w, h, pixels, 0, w);
        BufferedImage bi2 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        bi2.setRGB(0, 0, w, h, pixels, 0, w);
        return bi2;
    }

    /**
     * 解压RAR压缩文件到指定路径
     *
     * @param rarFile RAR压缩文件
     * @param dstDir  解压到的文件夹路径
     */
    public static List<File> unRarFile(String rarPath, String dstDir) throws Exception {

        List<File> resFiles = new ArrayList<>();
        File dstDiretory = new File(dstDir);
        if (!dstDiretory.exists()) {
            dstDiretory.mkdirs();
        }
        try {
            File rarFile = new File(rarPath);
            Archive archive = new Archive(new FileInputStream(rarFile));
            List<FileHeader> fileHeaders = archive.getFileHeaders();
            for (FileHeader fileHeader : fileHeaders) {
                if (fileHeader.isDirectory()) {
                    String fileName = fileHeader.getFileNameW();
                    if (!existZH(fileName)) {
                        fileName = fileHeader.getFileNameString();
                    }
                    File dir = new File(dstDir + File.separator + fileName);
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }
                } else {
                    String fileName = fileHeader.getFileNameW().trim();
                    if (!existZH(fileName)) {
                        fileName = fileHeader.getFileNameString().trim();
                    }
                    File file = new File(dstDir + File.separator + fileName);
                    try {
                        if (!file.exists()) {
                            if (!file.getParentFile().exists()) {
                                file.getParentFile().mkdirs();
                            }
                            file.createNewFile();
                        }
                        FileOutputStream os = new FileOutputStream(file);
                        archive.extractFile(fileHeader, os);
                        os.close();
                    } catch (Exception ex) {
                        throw ex;
                    }
                }
            }
            archive.close();
            List<File> files = FileUtil.loopFiles(dstDir);
            if (files.size() > 0) {
                resFiles = files;
            }

        } catch (Exception e) {
            throw e;
        }
        return resFiles;
    }

    /**
     * 解压文件使用
     *
     * @param filePath 带解压文件
     * @param destDir  解压到的目录
     */
    public static List<File> unzipFile(String zipFilePath, String outputFolder) {
        List<File> resFiles = new ArrayList<>();

        // 替换成了apache的 原有默认的会报错 Java原生库解压Zip流报MALFORMED错
        try (FileInputStream fis = new FileInputStream(zipFilePath);
             ZipArchiveInputStream zis = new ZipArchiveInputStream(new BufferedInputStream(fis))) {
            ZipArchiveEntry entry;
            while ((entry = zis.getNextZipEntry()) != null) {
                File entryDestination = new File(outputFolder, entry.getName());
                if (entry.isDirectory()) {
                    entryDestination.mkdirs();
                } else {
                    createParentDirs(entryDestination);
                    try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(entryDestination))) {
                        byte[] buffer = new byte[1024];
                        int read;
                        while ((read = zis.read(buffer)) != -1) {
                            bos.write(buffer, 0, read);
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<File> files = FileUtil.loopFiles(outputFolder);
        if (files.size() > 0) {
            resFiles = files;
        }
        return resFiles;

    }

    private static void createParentDirs(File file) throws IOException {
        File parentDir = file.getParentFile();
        if (parentDir != null && !parentDir.exists() && !parentDir.mkdirs()) {
            throw new IOException("Could not create parent directories for " + file);
        }
    }

    @PostMapping("upload")
    public ResultBean<Object> uploadExcelAnsc(MultipartHttpServletRequest request) {
        String uploadFile = uploadFile(request);
        return new ResultBean<>(uploadFile);
    }

//    public synchronized static void convertTiffToJpg(String tiffFilePath, String jpgFilePath) throws IOException {
//        // 注册 TwelveMonkeys ImageIO 插件
//        IIORegistry registry = IIORegistry.getDefaultInstance();
//        registry.registerServiceProvider(new TIFFImageReaderSpi());
//        registry.registerServiceProvider(new TIFFImageWriterSpi());
//
//        // 读取 TIF 图片
//        ImageReader reader = ImageIO.getImageReadersByFormatName("TIFF").next();
//        reader.setInput(ImageIO.createImageInputStream(new File(tiffFilePath)));
//
//        // 获取第一页 TIF 图片
//        BufferedImage tiffImage = reader.read(0);
//
//        // 创建 JPG 图片文件
//        File jpgFile = new File(jpgFilePath);
//
//        // 将 TIF 图片写入 JPG 文件
//        ImageWriter writer = ImageIO.getim(ImageIO.getImageWritersByFormatName("JPEG").next());
//        ImageOutputStream outputStream = ImageIO.createImageOutputStream(jpgFile);
//        writer.setOutput(outputStream);
//        writer.write(tiffImage);
//
//        // 关闭资源
//        reader.dispose();
//        writer.dispose();
//        outputStream.close();
//    }

    // 前台上传专用
    @PostMapping("uploadv2")
    public ResultBean<Object> uploadExcelAnscV2(MultipartHttpServletRequest request) {
        String uploadFile = uploadFilev2(request);
        return new ResultBean<>(uploadFile);
    }

    public String uploadFile(MultipartHttpServletRequest request) {
        List<MultipartFile> file = request.getFiles("file");
        return saveFile(file.get(0));
    }

    public String uploadFilev2(MultipartHttpServletRequest request) {
        List<MultipartFile> file = request.getFiles("file");
        return saveFilev2(file.get(0));
    }

    //解压文件 返回解压后全部文件路径

    @SneakyThrows
    public boolean checkFileRAR(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        if (originalFilename.toLowerCase().contains(".rar") || originalFilename.toLowerCase().contains(".zip")) {
            return true;
        } else {
            return false;
        }
    }

//    public static void main(String[] args) {
//        String filePath = "D:\\Users\\55419\\Desktop\\test.zip";
//        String destDir = "D:\\Users\\55419\\Desktop\\unzip";
//        List<File> files = unzipFile(filePath, destDir);
//        System.out.println(files.size());
//
//    }

    @SneakyThrows
    public List<File> checkFileUnzip(MultipartFile file) {
        List<File> res = new ArrayList<>();
        String originalFilename = file.getOriginalFilename();
        if (originalFilename.toLowerCase().contains(".rar") || originalFilename.toLowerCase().contains(".zip")) {
            String saveFileName = System.currentTimeMillis() + "___" + originalFilename;
            String finalFilePath = temprarPath + saveFileName;
            String unrarPath = temprarPath + System.currentTimeMillis() + "/unpath/";
            file.transferTo(new File(finalFilePath));
            if (FileUtil.exist(finalFilePath)) {
                // 根据数据进行解压判断
                if (originalFilename.contains(".zip")) {
                    System.setProperty("sun.zip.encoding", System.getProperty("sun.jnu.encoding"));
                    // 这就是全部解压的后的文件集合
                    res = unzipFile(finalFilePath, unrarPath);
                } else {
                    res = unRarFile(finalFilePath, unrarPath);
                }
            }
        }
        return res;
    }

    public String saveFile(MultipartFile fileOrg) {
        String front = "2";
        int id = userUtil.getUid();
        Integer integer = userUtil.getGid();
        String saveFileName = ""; //1682737346688.PDF
        String finalFilePath = "";
        if (fileOrg != null) {
            FileUtils.existsFile(uploadPath + localDateFilePath());///home/analysis/uploadFile/
            String fileRealName = fileOrg.getOriginalFilename();
            boolean israrunzip = checkFileRAR(fileOrg);
            // 处理解压测试
            if (israrunzip) {
                log.info("走了压缩文件测试");
                List<File> files = checkFileUnzip(fileOrg);
                log.info("压缩文件解压后的文件数量是" + files.size());
                List<String> paths = new ArrayList<>();

                for (File file1Param : files) {
                    String fileRealNameParam = file1Param.getName();
                    log.info("文件是+" + fileRealNameParam);
                    saveFileName = System.currentTimeMillis() + "___" + fileRealNameParam;//1697765010507___1682737346688.PDF
                    finalFilePath = uploadPath + localDateFilePath() + saveFileName;//  /home/analysis/uploadFile/    231019/     1697765010507___1682737346688.PDF
                    try {
                        if (fileRealNameParam.endsWith("tif") || fileRealNameParam.endsWith("tiff")) {
                            System.out.println("检测到是 TIF 文件:" + finalFilePath);
                            FileUtil.copy(file1Param, new File(finalFilePath), false);
                            saveFileName = saveFileName.replaceAll("-", "").replaceAll(" +", "").replaceAll("\\.tiff", "").replaceAll("\\.tif", "") + ".PNG";
                            convertTiffToJpg(finalFilePath, "/data/analysis/uploadFile/" + localDateFilePath() + saveFileName);
                        } else {
                            log.info("tiff else ");
                            log.info("finalFilePathgcr" + finalFilePath);
                            File file1 = new File(finalFilePath);
                            FileUtil.copy(file1Param, file1, false);
                            dealRuijin(finalFilePath, localDateFilePath() + saveFileName, front);
                        }
                    } catch (IOException e) {
                        uploadPath = "-1";
                        System.out.println("图片转换异常");
                        e.printStackTrace();
                    }
                    paths.add(localDateFilePath() + saveFileName);
                }
                String join = String.join("###", paths);
                return join;
            } else {
                saveFileName = System.currentTimeMillis() + "___" + fileRealName;//1697765010507___1682737346688.PDF
                finalFilePath = uploadPath + localDateFilePath() + saveFileName;//  /home/analysis/uploadFile/    231019/     1697765010507___1682737346688.PDF
                try {
                    if (fileOrg.getOriginalFilename().endsWith("tif") || fileOrg.getOriginalFilename().endsWith("tiff")) {
                        System.out.println("检测到是 TIF 文件:" + finalFilePath);
                        fileOrg.transferTo(new File(finalFilePath));
//                    BufferedImage read = ImageIO.read(new File(finalFilePath));
//                    read = ensureOpaque(read);
                        saveFileName = saveFileName.replaceAll("-", "").replaceAll(" +", "").replaceAll("\\.tiff", "").replaceAll("\\.tif", "") + ".PNG";
//                    System.out.println("新的文件___" + saveFileName);
//                    finalFilePath = uploadPath + localDateFilePath() + saveFileName;
//                    ImageIO.write(read, "jpg", new File(finalFilePath));
                        convertTiffToJpg(finalFilePath, "/data/analysis/uploadFile/" + localDateFilePath() + saveFileName);
                    } else {
                        log.info("tiff else ");
                        log.info("finalFilePathgcr" + finalFilePath);
                        File file1 = new File(finalFilePath);
                        fileOrg.transferTo(file1);
                        dealRuijin(finalFilePath, localDateFilePath() + saveFileName, front);

                    }

                } catch (IOException e) {
                    uploadPath = "-1";
                    System.out.println("图片转换异常");
                    e.printStackTrace();
                }
            }
        } else {
            System.out.println("文件是空的");
        }
        return localDateFilePath() + saveFileName;
    }

    public String saveFilev2(MultipartFile file) {
        String front = "1";
        int id = userUtil.getUid();
        Integer integer = userUtil.getGid();
        String saveFileName = ""; //1682737346688.PDF
        String finalFilePath = "";
        if (file != null) {
            FileUtils.existsFile(uploadPath + localDateFilePath());///home/analysis/uploadFile/
            String fileRealName = file.getOriginalFilename();
            saveFileName = System.currentTimeMillis() + "___" + fileRealName;//1697765010507___1682737346688.PDF
            finalFilePath = uploadPath + localDateFilePath() + saveFileName;//  /home/analysis/uploadFile/    231019/     1697765010507___1682737346688.PDF
            try {
                if (file.getOriginalFilename().endsWith("tif") || file.getOriginalFilename().endsWith("tiff")) {
                    System.out.println("检测到是 TIF 文件:" + finalFilePath);
                    file.transferTo(new File(finalFilePath));
//                    BufferedImage read = ImageIO.read(new File(finalFilePath));
//                    read = ensureOpaque(read);
                    saveFileName = saveFileName.replaceAll("-", "").replaceAll(" +", "").replaceAll("\\.tiff", "").replaceAll("\\.tif", "") + ".PNG";
//                    System.out.println("新的文件___" + saveFileName);
//                    finalFilePath = uploadPath + localDateFilePath() + saveFileName;
//                    ImageIO.write(read, "jpg", new File(finalFilePath));

                    convertTiffToJpg(finalFilePath, "/data/analysis/uploadFile/" + localDateFilePath() + saveFileName);


                } else {
                    log.info("tiff else ");
                    log.info("finalFilePathgcr" + finalFilePath);
                    File file1 = new File(finalFilePath);
                    file.transferTo(file1);
                    dealRuijin(finalFilePath, localDateFilePath() + saveFileName, front);

                }

            } catch (IOException e) {
                uploadPath = "-1";
                System.out.println("图片转换异常");
                e.printStackTrace();
            }
        } else {
            System.out.println("文件是空的");
        }

        return localDateFilePath() + saveFileName;
    }

    @SneakyThrows
    // front  1是前台 2是后台
    public void dealRuijin(String pathParam, String pathDb, String front) {
        //pdf sp 是单独处理的原始文件
        if (StrUtils.isRuiJin() && front.equals("2")) {
            // 个人文字自建库 上传解前md5校验 实在不知道怎么处理了.因为校验的是解析后的 ,但是提取正文的每次都不一样 无法使用
            log.info("瑞金服务器进行判断如果是标书则进行切割要正文内容");
            String md5 = "";
            if (FileUtil.exist(pathParam)) {
                File file = new File(pathParam);
                md5 = SecureUtil.md5(file);
            } else {
                log.error("文件不存在error ");
            }
            log.info("md5##" + md5);
            List<TextSelfMd5> fileMd5 = textSelfMd5Mapper.selectList(new QueryWrapper<TextSelfMd5>().eq("file_md5", md5));
            if (fileMd5.size() > 0) {
                System.out.println("有重复过滤入库 md5+" + md5);
                // 删除上传文件
                try {
                    FileUtil.del(pathParam);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                CheckUtil.check(false, "有重复文件 文件名称是+" + fileMd5.get(0).getFileName());
            } else {
                TextSelfMd5 textSelfDb = new TextSelfMd5();
                textSelfDb.setUid(userUtil.getUid());
                textSelfDb.setTableId(userUtil.getUid());
                String[] strings = pathDb.split("/");
                String fileName = strings[strings.length - 1];
                textSelfDb.setFileName(fileName);
                textSelfDb.setPath(pathDb);
                String pathFrom = uploadPath;
                String tempName = textSelfDb.getPath();
                textSelfDb.setFileMd5(md5);
                textSelfMd5Mapper.insert(textSelfDb);
            }
            String path = pathParam;
            if (FileUtil.exist(pathParam)) {
                try {
                    File file = new File(path);
                    PDDocument doc = Loader.loadPDF(file);
                    PDDocument docNew = new PDDocument();
                    int numberOfPages = doc.getNumberOfPages();
                    PDFTextStripper2 stripper2 = new PDFTextStripper2();
                    int startPage = 0;
                    int endPage = 9999;
                    for (int i = 0; i < numberOfPages; i++) {
                        stripper2.setStartPage(i);
                        stripper2.setEndPage(i);
                        String text = "";
                        try {
                            text = stripper2.getText(doc);//读取当前页的全部内容
                        } catch (Exception e) {

                        }

                        if (text.contains("参照以下提纲撰写，要求内容翔实、清晰，层次分明，标题突")) {
                            System.out.println("参照以下提纲撰写，要求内容翔实、清晰，层次分明++" + i);
                            startPage = i;
                        }
                        if (text.contains("论著之外的代表性研究成果和学术奖励")) {
                            System.out.println("论著之外的代表性研究成果和学术奖励++" + i);
                            if (i <= endPage) {
                                endPage = i;
                            }
                        }
                    }
                    if (startPage > 0 && endPage > 0) {

                        for (int i = startPage - 1; i <= endPage; i++) {
                            PDPage page = doc.getPage(i);
                            docNew.addPage(page);
                        }
                        docNew.save(path);
                    }
                    docNew.close();
                    doc.close();
                } catch (Exception e) {
                    log.error("预处理文档出错 不做处理了");
                    boolean exist = FileUtil.exist(pathParam);
                    log.error("文档路径 存在吗?+" + exist + "++path++" + pathParam);
//                    e.printStackTrace();

                }

            }
        }

        if (StrUtils.isRuiJin() && front.equals("1")) {
            // 个人文字自建库 上传解前md5校验 实在不知道怎么处理了.因为校验的是解析后的 ,但是提取正文的每次都不一样 无法使用
            log.info("瑞金服务器进行判断如果是标书则进行切割要正文内容");
            String md5 = "";
            if (FileUtil.exist(pathParam)) {
                File file = new File(pathParam);
                md5 = SecureUtil.md5(file);
            }
            log.info("md5##" + md5);
//            List<TextSelfMd5> fileMd5 = textSelfMd5Mapper.selectList(new QueryWrapper<TextSelfMd5>().eq("file_md5", md5));
            String path = pathParam;
            if (FileUtil.exist(pathParam)) {
                try {
                    File file = new File(path);
                    PDDocument doc = Loader.loadPDF(file);
                    PDDocument docNew = new PDDocument();
                    int numberOfPages = doc.getNumberOfPages();
                    PDFTextStripper2 stripper2 = new PDFTextStripper2();
                    int startPage = 0;
                    int endPage = 9999;
                    for (int i = 0; i < numberOfPages; i++) {
                        stripper2.setStartPage(i);
                        stripper2.setEndPage(i);
                        String text = "";
                        try {
                            text = stripper2.getText(doc);//读取当前页的全部内容
                        } catch (Exception e) {

                        }
                        if (text.contains("参照以下提纲撰写，要求内容翔实、清晰，层次分明，标题突")) {
                            System.out.println("参照以下提纲撰写，要求内容翔实、清晰，层次分明++" + i);
                            startPage = i;
                        }
                        if (text.contains("论著之外的代表性研究成果和学术奖励")) {
                            System.out.println("论著之外的代表性研究成果和学术奖励++" + i);
                            if (i <= endPage) {
                                endPage = i;
                            }
                        }
                    }
                    if (startPage > 0 && endPage > 0) {

                        for (int i = startPage - 1; i <= endPage; i++) {
                            PDPage page = doc.getPage(i);
                            docNew.addPage(page);
                        }
                        docNew.save(path);
                    }
                    docNew.close();
                    doc.close();
                } catch (Exception e) {
                    log.error("预处理文档出错 不做处理了");
                    boolean exist = FileUtil.exist(pathParam);
                    log.error("文档路径 存在吗?+" + exist + "++path++" + pathParam);
//                    e.printStackTrace();
                }

            }
        }


    }


}
